<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>05_函数组件拓展</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
    <div id="app"></div>
    <script type="text/babel">
        let app = document.getElementById("app")
        let {Fragment,Component} = React
        /*
        * 函数组件可以根据功能拓展出一些针对性较强的逻辑组件
        * 1、代理组件（Proxy Component）
        *   我们在项目中需要频繁使用type值为button的按钮,就可以用Button组件代替原先的button标签，使button的type属性写死
        * */
        /*function Button(props){
            return <button type="button" {...props}>{props.children}</button>
        }*/
        const Button=(props)=>(
            <button type="button" {...props}>{props.children}</button>
        )
        ReactDOM.render(<Button className="login" size="20">登录按钮</Button>,app)

        /*
        * 2、容器组件（Container Component）
        *   只接收数据，用于展示，没有任何的逻辑功能
        * */
        /*function NewsList({newsArr}){
            return (
                <ul>
                    {newsArr.map((v,i)=><li key={i}>{v}</li>)}
                </ul>
            )
        }*/
        const NewsList=({newsArr})=>(
            <ul>
                {newsArr.map((v,i)=><li key={i}>{v}</li>)}
            </ul>
        )
        let news = [
            "新闻1","新闻2","新闻3","新闻4","新闻5","新闻6"
        ]
        ReactDOM.render(<NewsList newsArr={news}></NewsList>,app)

        /*
        * 3、高阶组件（HOC）
        *   具体而言，高阶组件是参数为组件，返回值为新组件的函数。接收的组件的类型可以是函数组件也可以是clss组件
        * */
        // 需求，项目里有好多个组件在初始化的时候需要从localStorage里获取数据，对自身的state进行初始化
        /*
        //正常使用
        class MyComponent extends React.Component{
            state={
                info:localStorage.getItem("user") || ""
            }
            render(){
                return <div>用户的信息：{this.state.info}</div>
            }
        }*/

        //HOC
        const initLSData = (key) => (MyComponent) => {
            return class extends React.Component{
                constructor(props) {
                    super(props);
                    this.state={
                        info:localStorage.getItem(key) || key
                    }
                }
                render() {
                    return (
                        <MyComponent info={this.state.info}></MyComponent>
                    );
                }
            }
        }

        class Child1 extends React.Component{
            render() {
                return (
                    <div>
                        初始化的1s数据是：{this.props.info}
                    </div>
                );
            }
        }
        class Child2 extends React.Component{
            render() {
                return (
                    <div>
                        初始化的2s数据是：{this.props.info}
                    </div>
                );
            }
        }
        const LsComponent1 = initLSData("token")(Child1);
        const LsComponent2 = initLSData("user")(Child2);

        //通过“函数柯里化”来处理多次传值的高阶组件
        //函数柯里化：通过函数调用后继续返回函数的方式，实现多次的接收参数并最后统一处理的函数编码形式
        function sum(a){
            return b=>{
                return c=>{
                    return a+b+c
                }
            }
        }
        console.log( sum(5)(6)(7) )


        ReactDOM.render((
            <Fragment>
                <LsComponent1></LsComponent1>
                <LsComponent2></LsComponent2>
            </Fragment>
        ),app)
    </script>
</body>
</html>